﻿using CardPlay.Model.CardModel;
using CardPlay.Model.GameModel;
using CardPlay.Model.GameModel.Actions;
using CardPlay.Model.GameModel.Presentation;
using CardPlay.Model.Layout;

namespace CardPlay.DemoPack.Games.CanfieldVariants
{
    [Game("9E7BC9AC-63E4-48B4-8B51-BFD35BBE1D30", LevelOfDifficulty.Easy, LevelOfSkill.MostlyChance, DurationOfPlay.Within5To10Minutes, Family = FamilyName)]
    public class Canfield : StandardCardGame
    {
        public const string FamilyName = "Canfield";

        public Canfield()
        {
            NamesOfAdditionalPiles.Add(Reserve);

            AutoPlayReserve = true;
            TableauBuildSequence = CardFaceSequence.AlternatingColorDescendingRank;
        }

        public override ILayoutSite CreatePresentation(IPresentationContext presentation)
        {
            var root = presentation.CreateGridLayout(2, 1);

            {
                var column = presentation.CreateColumnLayout();
                root.Add(column);

                column.Add(presentation.CreateStockWasteLayout(this));
                column.Add(presentation.CreatePileVisual(Reserve, presentation.HorizontalStackingStyle()));
            }

            {
                var column = presentation.CreateColumnLayout();
                root.Add(column);

                var foundations = presentation.CreateRowLayout();
                foundations.MinimumSize = presentation.MinimumWasteSize();
                presentation.AddPiles(foundations, NamesOfFoundations, presentation.StyleForRepeatedRankFoundation(this, FoundationBaseRank, TotalDecks));

                var tableau = presentation.AddTableauPiles(this, presentation.CreateRowLayout());

                column.Add(foundations);
                column.Add(tableau);

                OnTableauLayoutCreated(presentation, tableau);
            }

            return root;
        }

        protected bool AutoPlayReserve { get; set; }

        protected virtual void OnTableauLayoutCreated(IPresentationContext presentation, CompositeLayout layout)
        {
        }

        protected override void PrepareDealScript(DealScript script)
        {
            script.DealCardTo(Foundation1);
            script.Deal("12 down,1 up").To(Reserve);
            script.DealCardToEach(NamesOfTableaus);
            script.DealRemainingFaceDownTo(Stock);
        }

        protected override void OverridePlayingRules(PlayingRules playingRules)
        {
            playingRules.At(AnyReserve).Permit<RemovePileAction>().When(Action.IsActingOnFaceUpTopCard);
        }

        protected override bool AllowedToBuildEmptyTableau(MovePileAction action)
        {
            return action.FromLocation.Matches(Reserve) || 
                    (action.FromLocation.Matches(Waste) && this[Reserve].IsEmpty && action.PileBeingMoved.BottomCard.Rank != FoundationBaseRank);
        }

        protected override void OnTransactionEnding()
        {
            if (AutoPlayReserve) this.FillFromReserveEmptyPilesMatching(AnyTableau);
            this.FlipFaceDownTopCardsInPilesMatching(Reserve);
        }
    }
}
